# -*- coding:utf-8 -*-

import os
import sys
import requests
from .redis_connection import fetch_redis
from .police import CallPolice
from lib import request_id
from constants import host_ip, host_port
from .test_report.generate_test_report import GenerateTestReport

test_case_dir_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'test_case')


class Step(object):
    """
    步骤生成器
    """

    def __init__(self):
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        return self.index

    @property
    def n(self):
        """
        像属性一样使用
        :return:
        """
        return next(self)


class UpdateDate(object):

    def __init__(self):
        self.base_url = f'http://{host_ip}:{host_port}/'

    def upload_send(self, url, data):
        resp = requests.post(url, data=data)
        if resp.status_code == 200:
            data = resp.json()
            if data.get('status') == 'fail':
                print(f'code: {data.get("code")},  message: {data.get("message")}')
        else:
            return resp.json()

    def base_case_update(self, data):
        # 数据更新API
        update_url = self.base_url + 'update_base_case/'
        self.upload_send(update_url, data)

    def regression_update(self, data):
        # 回归测试表
        # 回归测试数据更新API
        update_url = self.base_url + 'update_regression/'
        self.upload_send(update_url, data)

    def regression_info_update(self, data):
        # 回归测试数据更新API
        update_url = self.base_url + 'update_regression_info/'
        self.upload_send(update_url, data)


def police(status):
    """
    报警信息
    :param status:
    :return:
    """
    redis = fetch_redis()
    token = redis.hget(request_id, 'police')
    if not token:
        return
    send = CallPolice(token)
    if status:
        text = f'info:测试用例: [{redis.hget(request_id, "case_name")}] 测试结束,  测试结果: [success]'
        send.send_text(text)
    else:
        text = f'info:测试用例: [{redis.hget(request_id, "case_name")}] 测试结束, 测试结果: [fail]'
        send.send_text(text)
    return

def regression_decorator(func):
    """
    回归测试用例装饰器： 工作职责：
        1、记录进程PID
        2、更新任务状态
        3、失败报警
    """
    def inner(*args, **kwargs):
        request_id = sys.argv[-1:].pop()
        if not request_id:
            raise ValueError('执行用例时未指定request id')
        # 更新测试状态
        update = UpdateDate()
        update.regression_info_update({'request_id': request_id, 'status': 'running'})
        pid = os.getpid()
        redis = fetch_redis()
        redis.hset('process_pid', request_id, pid)
        e = None
        try:
            func(*args, **kwargs)
        except Exception as e:
            pass
        regression_uid = redis.hget(request_id, 'regression')
        case_number_query_key = redis.hget(request_id, 'case_number_query_key')
        number = redis.get(case_number_query_key)
        value = int(number) - 1
        if value == 0:
            data = {'regression': regression_uid, 'status': 'success'}
            update.regression_update(data)
            redis.delete(case_number_query_key)
        else:
            redis.set(case_number_query_key, value)
        # 测试结束钉钉报警
        police(False if e else True)
        redis.hdel('process_pid', request_id)
        redis.delete(request_id)
        if e:
            raise e
        return True
    return inner


def base_case_decorator(func):
    """
    回归测试用例装饰器： 工作职责：
        1、记录进程PID
        2、更新任务状态
        3、失败报警
    """
    def inner(*args, **kwargs):
        request_id = sys.argv[-1:].pop()
        if not request_id:
            raise ValueError('执行用例时未指定request id')
        # 更新测试状态
        update = UpdateDate()
        update.base_case_update({'request_id': request_id, 'status': 'running'})
        pid = os.getpid()
        redis = fetch_redis()
        redis.hset('process_pid', request_id, pid)
        e = None
        try:
            func(*args, **kwargs)
        except Exception as e:
            update.base_case_update({'request_id': request_id, 'status': 'fail'})
        # 测试结束钉钉报警
        police(False if e else True)
        print(redis.hgetall(request_id))
        if redis.hget(request_id, 'report_status') == '1':
            # 生成测试报告
            case_file= os.path.join(test_case_dir_path, 'base_case', redis.hget(request_id, 'case_name') + '.py')
            log_file_path = redis.hget(request_id, 'log_path')
            report= GenerateTestReport(case_file, log_file_path)
            report_path = report.generateHtml()
            update.base_case_update({'request_id': request_id, 'report_path': report_path})
        # 清理环境
        redis.hdel('process_pid', request_id)
        redis.delete(request_id)
        if e:
            raise e
        return True
    return inner
